#pragma once
#include <sys/socket.h>
#include <netinet/in.h>
#include <cstring>
#include <atomic>
#include <unistd.h>
#include <string>
 #include <sys/wait.h>
 #include<thread>
 #include"ThreadPool.hpp"
/*****************************
 * v1 单进程tcp通信，只能完成单连接交互
 * 
 * ************************** */

/**************************
 *  v2 多进程服务器--支持连接多个客户端
 * ************************ */


/*********************************************
 *      v3线程池
 ************** **************************** */

static const int gport = -1;
static const int gsockfd = -1;
static const int gbacklog = 5;

using task_t=std::function<void()>;
class TcpServer
{
public:
    TcpServer(int port = gport)
        : _port(port), _listenfd(gsockfd), _stop(true)
    {
    }

    void Init()
    {
        // 创建套接字
        _listenfd = socket(AF_INET, SOCK_STREAM, 0);
        if (_listenfd < 0)
        {
            std::cout << "创建套接字失败!!!" << std::endl;
            exit(-1);
        }
        std::cout << "创建套接字成功!sockfd:" << _listenfd << std::endl;

        struct sockaddr_in local;
        bzero(&local, sizeof(local));
        local.sin_family = AF_INET;
        local.sin_port = htons(_port);
        local.sin_addr.s_addr = INADDR_ANY;

        // 绑定端口

        int n = bind(_listenfd, (struct sockaddr *)&local, sizeof(local));
        if (n < 0)
        {
            std::cout << "绑定端口失败" << std::endl;
            exit(-2);
        }
        std::cout << "绑定端口成功!port:" << _port << std::endl;

        // 设置为监听状态
        int m = listen(_listenfd, gbacklog);
        if (m == -1)
        {
            std::cout << "设置监听状态失败！" << std::endl;
            exit(-3);
        }
        std::cout<<"设置为监听状态成功!"<<std::endl;

        ThreadPool<task_t>::GetInstance()->Start();
        std::cout<<"线程池启动"<<std::endl;
    }

    void Start()
    {
        _stop = false;
        while (!_stop)
        {
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);
            int sockfd = accept(_listenfd, (struct sockaddr *)&peer, &len);
            if (sockfd < 0)
            {
                std::cout << "获取连接失败" << std::endl;
                continue;
            }
            std::cout << "获取新连接,sockfd:" << sockfd << std::endl;

            //v1
            // Server(sockfd);
            // close(sockfd);
        
            //v2 多进程版本
            // pid_t id=fork();
            // if(id<0){
            //     std::cout<<"创建子进程失败"<<std::endl;
            //     continue;
            // }
            // else if(id==0){
            //     //子进程
            //     //让孙子进程负责
            //     if(fork()>0)
            //         exit(0);
            //     //孙子进程执行任务
            //     Server(sockfd);
            // }

            // //父进程回收子进程
            // close(sockfd);
            // int ret=waitpid(-1,nullptr,0);
            // if(ret==id){
            //     //do nothing
            // }
        
            //v3多线程模式
            // std::thread t1([sockfd,this](){
            //     Server(sockfd);
            // });

            // t1.detach();

            auto task=std::bind(&TcpServer::Server,this,sockfd);
            ThreadPool<task_t>::GetInstance()->Push(task);
            
        }
    }

    void Server(int sockfd)
    {
        char buffer[1024];
        while (true)
        {
            // 进行互相读写
            int n = read(sockfd, buffer, sizeof(buffer) - 1);
            if (n > 0)
            {
                buffer[n] = 0;
                std::cout<<"client say:"<<buffer<<std::endl;
                std::string ret = "server say:";
                ret += buffer;
                int m=send(sockfd,ret.c_str(),ret.size(),0);
                if(m<0){
                    std::cout<<"send error"<<std::endl;
                }
            }
            else
            {
                // 不处理错误
                break;
            }
        }
        close(sockfd);
    }

private:
    int _port;
    int _listenfd;
    std::atomic<bool> _stop;
};